package com.wzh.codegen.biz.service.impl;

import cn.hutool.core.map.MapUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wzh.codegen.biz.domain.dto.*;
import com.wzh.codegen.biz.domain.entity.CodegenTableConfig;
import com.wzh.codegen.biz.service.CodegenTableConfigService;
import com.wzh.codegen.biz.service.DatasourceService;
import com.wzh.codegen.biz.util.CodegenUtils;
import com.wzh.codegen.biz.util.DatabaseUtils;
import com.wzh.codegen.biz.util.TemplateUtils;
import com.wzh.common.general.exception.CustomerException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.wzh.codegen.biz.service.impl.CodegenTableConfigServiceImpl.getDefaultFormType;
import static com.wzh.codegen.biz.service.impl.CodegenTableConfigServiceImpl.isCommonField;

/**
 * 代码生成服务实现类
 *
 * @author wzh
 * @since 2024-01-01
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CodegenServiceImpl implements com.wzh.codegen.biz.service.CodegenService {

    private final DatasourceService datasourceService;
    private final CodegenTableConfigService codegenTableConfigService;
    private final TemplateUtils templateUtils;
    private final DatabaseUtils databaseUtils;
    private final ObjectMapper objectMapper;

    @Override
    public String generateService(CodegenServiceDTO dto) {
        try {
            // 准备模板变量
            Map<String, Object> variables = prepareServiceVariables(dto);

            // 生成代码文件
            Map<String, String> files = templateUtils.generateServiceFiles(variables);

            log.info("成功生成微服务代码，服务名: {}, 文件数量: {}", dto.getServiceName(), files.size());
            return "代码生成成功，共生成 " + files.size() + " 个文件";
        } catch (Exception e) {
            log.error("生成微服务代码失败", e);
            throw new CustomerException("生成微服务代码失败: " + e.getMessage());
        }
    }

    @Override
    public ResponseEntity<Resource> downloadService(CodegenServiceDTO dto) {
        try {
            // 准备模板变量
            Map<String, Object> variables = prepareServiceVariables(dto);

            // 生成代码文件
            Map<String, String> files = templateUtils.generateServiceFiles(variables);

            // 创建ZIP压缩包
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            try (ZipArchiveOutputStream zos = new ZipArchiveOutputStream(baos)) {
                for (Map.Entry<String, String> entry : files.entrySet()) {
                    ZipArchiveEntry zipEntry = new ZipArchiveEntry(entry.getKey());
                    zos.putArchiveEntry(zipEntry);
                    zos.write(entry.getValue().getBytes(StandardCharsets.UTF_8));
                    zos.closeArchiveEntry();
                }
            }

            ByteArrayResource resource = new ByteArrayResource(baos.toByteArray());

            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + dto.getServiceName() + ".zip")
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .body(resource);
        } catch (Exception e) {
            log.error("下载微服务代码失败", e);
            throw new CustomerException("下载微服务代码失败: " + e.getMessage());
        }
    }

    @Override
    public String generateTable(CodegenTableDTO dto) {
        try {
            // 获取数据源信息
            DatasourceDTO datasource = datasourceService.getByIdVo(dto.getDatasourceId());

            // 获取表结构信息
            List<Map<String, Object>> columns = databaseUtils.getTableColumns(datasource, dto.getTableName());

            // 准备模板变量
            Map<String, Object> variables = prepareTableVariables(dto, datasource, columns);

            // 生成代码文件
            Map<String, String> files = templateUtils.generateTableFiles(variables);

            // 将代码写入到指定位置
            writeFilesToDisk(files, dto.getGeneratePath(), dto.getPackageName());

            log.info("成功生成表代码到指定位置，表名: {}, 文件数量: {}, 生成路径: {}", dto.getTableName(), files.size(), dto.getGeneratePath());
            return "代码生成成功，共生成 " + files.size() + " 个文件到路径: " + dto.getGeneratePath();
        } catch (Exception e) {
            log.error("生成表代码失败", e);
            throw new CustomerException("生成表代码失败: " + e.getMessage());
        }
    }

    @Override
    public ResponseEntity<Resource> downloadTable(CodegenTableDTO dto) {
        try {
            // 获取数据源信息
            DatasourceDTO datasource = datasourceService.getByIdVo(dto.getDatasourceId());

            // 获取表结构信息
            List<Map<String, Object>> columns = databaseUtils.getTableColumns(datasource, dto.getTableName());

            // 准备模板变量
            Map<String, Object> variables = prepareTableVariables(dto, datasource, columns);
            variables.put("idFieldType", columns.getFirst().get("javaFieldType"));
            // 生成代码文件
            Map<String, String> files = templateUtils.generateTableFiles(variables);

            // 创建ZIP压缩包
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            try (ZipArchiveOutputStream zos = new ZipArchiveOutputStream(baos)) {
                for (Map.Entry<String, String> entry : files.entrySet()) {
                    ZipArchiveEntry zipEntry = new ZipArchiveEntry(entry.getKey());
                    zos.putArchiveEntry(zipEntry);
                    zos.write(entry.getValue().getBytes(StandardCharsets.UTF_8));
                    zos.closeArchiveEntry();
                }
            }

            ByteArrayResource resource = new ByteArrayResource(baos.toByteArray());

            return ResponseEntity.ok()
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + dto.getEntityName() + ".zip")
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .body(resource);
        } catch (Exception e) {
            log.error("下载表代码失败", e);
            throw new CustomerException("下载表代码失败: " + e.getMessage());
        }
    }

    @Override
    public void syncTable(Long datasourceId, String tableName) {
        try {
            // 获取数据源信息
            DatasourceDTO datasource = datasourceService.getByIdVo(datasourceId);

            // 同步表结构
            databaseUtils.syncTableStructure(datasource, tableName);

            log.info("成功同步表结构，数据源ID: {}, 表名: {}", datasourceId, tableName);
        } catch (Exception e) {
            log.error("同步表结构失败", e);
            throw new CustomerException("同步表结构失败: " + e.getMessage());
        }
    }

    @Override
    public void syncCode(CodegenTableDTO dto) {
        try {
            // 获取数据源信息
            DatasourceDTO datasource = datasourceService.getByIdVo(dto.getDatasourceId());

            // 获取表结构信息
            List<Map<String, Object>> columns = databaseUtils.getTableColumns(datasource, dto.getTableName());

            // 同步代码
            CodegenUtils.syncGeneratedCode(dto, columns);

            log.info("成功同步代码，表名: {}", dto.getTableName());
        } catch (Exception e) {
            log.error("同步代码失败", e);
            throw new CustomerException("同步代码失败: " + e.getMessage());
        }
    }

    @Override
    public List<Map<String, Object>> getTables(Long datasourceId) {
        try {
            // 获取数据源信息
            DatasourceDTO datasource = datasourceService.getByIdVo(datasourceId);

            // 获取表列表
            return databaseUtils.getTables(datasource);
        } catch (Exception e) {
            log.error("获取表列表失败", e);
            throw new CustomerException("获取表列表失败: " + e.getMessage());
        }
    }

    @Override
    public List<Map<String, Object>> getColumns(Long datasourceId, String tableName) {
        try {
            // 获取数据源信息
            DatasourceDTO datasource = datasourceService.getByIdVo(datasourceId);

            // 获取字段列表
            return databaseUtils.getTableColumns(datasource, tableName);
        } catch (Exception e) {
            log.error("获取字段列表失败", e);
            throw new CustomerException("获取字段列表失败: " + e.getMessage());
        }
    }

    @Override
    public void createTable(CodegenTableDTO dto) {
        try {
            // 获取数据源信息
            DatasourceDTO datasource = datasourceService.getByIdVo(dto.getDatasourceId());

            // 转换字段信息
            List<Map<String, Object>> columns = convertColumnsForCreation(dto.getColumns());

            // 创建表
            databaseUtils.createTable(datasource, dto.getTableName(), columns, dto);

            log.info("成功创建表: {}", dto.getTableName());
        } catch (Exception e) {
            log.error("创建表失败", e);
            throw new CustomerException("创建表失败: " + e.getMessage());
        }
    }


    @Override
    public String generateSql(CodegenTableDTO tableDTO) {
        try {
            // 获取数据源信息
            DatasourceDTO datasource = datasourceService.getByIdVo(tableDTO.getDatasourceId());

            // 转换字段信息
            List<Map<String, Object>> columns = convertColumnsForCreation(tableDTO.getColumns());

            // 生成SQL脚本
            return databaseUtils.generateCreateTableSql(tableDTO.getTableName(), columns, datasource.getDbType(), tableDTO.getTableComment());

        } catch (Exception e) {
            log.error("生成SQL失败: {}", tableDTO.getTableName(), e);
            throw new CustomerException("生成SQL失败: " + e.getMessage());
        }
    }

    @Override
    public String generateServiceCode(CodegenTableDTO tableDTO) {
        try {
            // 准备模板变量
            Map<String, Object> variables = prepareTableVariables(tableDTO);

            // 转换字段信息
            List<Map<String, Object>> columns = convertColumnsForGeneration(tableDTO.getColumns());
            variables.put("columns", columns);

            // 生成Service代码
            Map<String, String> files = templateUtils.generateTableFiles(variables);

            // 返回Service代码
            String servicePath = "src/main/java/" + tableDTO.getPackageName().replace(".", "/") + "/service/" + tableDTO.getEntityName() + "Service.java";
            return files.get(servicePath);

        } catch (Exception e) {
            log.error("生成Service失败: {}", tableDTO.getEntityName(), e);
            throw new CustomerException("生成Service失败: " + e.getMessage());
        }
    }

    @Override
    public String generateEntity(CodegenTableDTO tableDTO) {
        try {
            // 准备模板变量
            Map<String, Object> variables = prepareTableVariables(tableDTO);

            // 转换字段信息
            List<Map<String, Object>> columns = convertColumnsForGeneration(tableDTO.getColumns());
            variables.put("columns", columns);
            variables.put("generateEntity", true);
            variables.put("idFieldType", columns.getFirst().get("javaFieldType"));
            // 过滤通用字段
            List<Map<String, Object>>  entityColumns = columns.stream().filter(column -> !isCommonField(MapUtil.getStr(column,"columnName"))).toList();
            variables.put("entityColumns", entityColumns);
            // 生成实体类代码
            Map<String, String> files = templateUtils.generateTableFiles(variables);

            // 返回实体类代码
            String entityPath = "src/main/java/" + tableDTO.getPackageName().replace(".", "/") + "/domain/entity/" + tableDTO.getEntityName() + ".java";
            return files.get(entityPath);

        } catch (Exception e) {
            log.error("生成实体类失败: {}", tableDTO.getEntityName(), e);
            throw new CustomerException("生成实体类失败: " + e.getMessage());
        }
    }

    @Override
    public String generateMapper(CodegenTableDTO tableDTO) {
        try {
            // 准备模板变量
            Map<String, Object> variables = prepareTableVariables(tableDTO);

            // 转换字段信息
            List<Map<String, Object>> columns = convertColumnsForGeneration(tableDTO.getColumns());
            variables.put("columns", columns);

            // 生成Mapper代码
            Map<String, String> files = templateUtils.generateTableFiles(variables);

            // 返回Mapper代码
            String mapperPath = "src/main/java/" + tableDTO.getPackageName().replace(".", "/") + "/mapper/" + tableDTO.getEntityName() + "Mapper.java";
            return files.get(mapperPath);

        } catch (Exception e) {
            log.error("生成Mapper失败: {}", tableDTO.getEntityName(), e);
            throw new CustomerException("生成Mapper失败: " + e.getMessage());
        }
    }

    @Override
    public String generateDTO(CodegenTableDTO tableDTO) {
        try {
            // 准备模板变量
            Map<String, Object> variables = prepareTableVariables(tableDTO);

            // 转换字段信息
            List<Map<String, Object>> columns = convertColumnsForGeneration(tableDTO.getColumns());
            variables.put("columns", columns);
            variables.put("generateDTO", true);

            // 生成DTO代码
            Map<String, String> files = templateUtils.generateTableFiles(variables);

            // 返回DTO代码
            String dtoPath = "src/main/java/" + tableDTO.getPackageName().replace(".", "/") + "/domain/dto/" + tableDTO.getEntityName() + "DTO.java";
            return files.get(dtoPath);

        } catch (Exception e) {
            log.error("生成DTO失败: {}", tableDTO.getEntityName(), e);
            throw new CustomerException("生成DTO失败: " + e.getMessage());
        }
    }

    @Override
    public String generateServiceImpl(CodegenTableDTO tableDTO) {
        try {
            // 准备模板变量
            Map<String, Object> variables = prepareTableVariables(tableDTO);

            // 转换字段信息
            List<Map<String, Object>> columns = convertColumnsForGeneration(tableDTO.getColumns());
            variables.put("columns", columns);

            // 生成ServiceImpl代码
            Map<String, String> files = templateUtils.generateTableFiles(variables);

            // 返回ServiceImpl代码
            String serviceImplPath = "src/main/java/" + tableDTO.getPackageName().replace(".", "/") + "/service/impl/" + tableDTO.getEntityName() + "ServiceImpl.java";
            return files.get(serviceImplPath);

        } catch (Exception e) {
            log.error("生成ServiceImpl失败: {}", tableDTO.getEntityName(), e);
            throw new CustomerException("生成ServiceImpl失败: " + e.getMessage());
        }
    }

    @Override
    public String generateController(CodegenTableDTO tableDTO) {
        try {
            // 准备模板变量
            Map<String, Object> variables = prepareTableVariables(tableDTO);

            // 转换字段信息
            List<Map<String, Object>> columns = convertColumnsForGeneration(tableDTO.getColumns());
            variables.put("columns", columns);

            // 生成Controller代码
            Map<String, String> files = templateUtils.generateTableFiles(variables);

            // 返回Controller代码
            String controllerPath = "src/main/java/" + tableDTO.getPackageName().replace(".", "/") + "/controller/" + tableDTO.getEntityName() + "Controller.java";
            return files.get(controllerPath);

        } catch (Exception e) {
            log.error("生成Controller失败: {}", tableDTO.getEntityName(), e);
            throw new CustomerException("生成Controller失败: " + e.getMessage());
        }
    }

    @Override
    public List<Map<String, Object>> syncTableStructure(Long datasourceId, Long tableId) {
        try {
            // 获取数据源信息
            DatasourceDTO datasource = datasourceService.getByIdVo(datasourceId);

            // 获取表信息
            CodegenTableConfigDTO tableConfig = this.codegenTableConfigService.getTableConfig(tableId);

            // 获取表字段信息
            List<Map<String, Object>> columnInfos = databaseUtils.getTableColumns(datasource, tableConfig.getTableName());

            // 转json并保存
            // 转换为CodegenColumnDTO
            List<CodegenColumnDTO> columns = columnInfos.stream().map(columnInfo -> {
                CodegenColumnDTO column = new CodegenColumnDTO();
                column.setColumnName((String) columnInfo.get("columnName"));
                column.setColumnType((String) columnInfo.get("dataType"));
                column.setColumnLength((Integer) columnInfo.get("columnSize"));
                column.setColumnScale((Integer) columnInfo.get("decimalDigits"));
                column.setColumnComment((String) columnInfo.get("columnComment"));
                column.setIsPrimaryKey((Boolean) columnInfo.get("isPrimaryKey"));
                column.setIsAutoIncrement((Boolean) columnInfo.get("isAutoIncrement"));
                column.setIsNullable((Boolean) columnInfo.get("nullable"));
                column.setDefaultValue((String) columnInfo.get("columnDefault"));
                column.setJavaFieldName((String) columnInfo.get("javaFieldName"));
                column.setJavaFieldType((String) columnInfo.get("javaFieldType"));

                // 设置默认的显示和查询配置
                column.setShowInList(!isCommonField(column.getColumnName()));
                column.setShowInForm(!isCommonField(column.getColumnName()) && !column.getIsPrimaryKey());
                column.setShowInQuery(false);
                column.setQueryType("=");
                column.setFormType(getDefaultFormType(column.getJavaFieldType()));

                return column;
            }).toList();

            CodegenTableConfig codegenTableConfig = new CodegenTableConfig();
            codegenTableConfig.setColumnsConfig(objectMapper.writeValueAsString(columns));
            codegenTableConfig.setId(tableId);
            this.codegenTableConfigService.updateById(codegenTableConfig);

            log.info("同步表结构成功: {}.{}, 字段数量: {}", datasource.getDatabaseName(), tableConfig.getTableName(), columns.size());
            return columnInfos;

        } catch (Exception e) {
            log.error("同步表结构失败: datasourceId={}, tableId={}", datasourceId, tableId, e);
            throw new CustomerException("同步表结构失败: " + e.getMessage());
        }
    }

    /**
     * 准备服务生成的模板变量
     */
    private Map<String, Object> prepareServiceVariables(CodegenServiceDTO dto) {
        Map<String, Object> variables = new HashMap<>();
        variables.put("serviceName", dto.getServiceName());
        variables.put("serviceDescription", dto.getServiceDescription());
        variables.put("packageName", dto.getPackageName());
        variables.put("generatePath", dto.getGeneratePath());
        variables.put("author", dto.getAuthor());
        variables.put("includeApi", dto.getIncludeApi());
        variables.put("includeSwagger", dto.getIncludeSwagger());
        variables.put("includeFeign", dto.getIncludeFeign());
        variables.put("date", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        variables.put("datetime", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        return variables;
    }

    /**
     * 准备表生成的模板变量（简化版本）
     */
    private Map<String, Object> prepareTableVariables(CodegenTableDTO dto) {
        Map<String, Object> variables = new HashMap<>();
        variables.put("tableName", dto.getTableName());
        variables.put("tableComment", dto.getTableComment());
        variables.put("entityName", dto.getEntityName());
        variables.put("packageName", dto.getPackageName());
        variables.put("generatePath", dto.getGeneratePath());
        variables.put("author", dto.getAuthor());
        variables.put("generateController", dto.getGenerateController());
        variables.put("generateService", dto.getGenerateService());
        variables.put("generateMapper", dto.getGenerateMapper());
        variables.put("generateXml", dto.getGenerateXml());
        variables.put("date", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        variables.put("datetime", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        return variables;
    }

    /**
     * 准备表生成的模板变量（完整版本）
     */
    private Map<String, Object> prepareTableVariables(CodegenTableDTO dto, DatasourceDTO datasource, List<Map<String, Object>> columns) {
        Map<String, Object> variables = new HashMap<>();
        variables.put("tableName", dto.getTableName());
        variables.put("tableComment", dto.getTableComment());
        variables.put("entityName", dto.getEntityName());
        variables.put("packageName", dto.getPackageName());
        variables.put("generatePath", dto.getGeneratePath());
        variables.put("author", dto.getAuthor());
        variables.put("columns", dto.getColumns());
        // 过滤通用字段
        variables.put("entityColumns", columns.stream().filter(column -> !isCommonField(MapUtil.getStr(column,"columnName"))).toList());
        variables.put("generateController", dto.getGenerateController());
        variables.put("generateService", dto.getGenerateService());
        variables.put("generateMapper", dto.getGenerateMapper());
        variables.put("generateEntity", true);
        variables.put("generateDTO", true);
        variables.put("generateXml", dto.getGenerateXml());
        variables.put("datasource", datasource);
        variables.put("tableColumns", columns);
        variables.put("date", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        variables.put("datetime", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        return variables;
    }

    /**
     * 转换字段信息用于创建表
     */
    private List<Map<String, Object>> convertColumnsForCreation(List<com.wzh.codegen.biz.domain.dto.CodegenColumnDTO> columnDTOs) {
        List<Map<String, Object>> columns = new ArrayList<>();

        for (com.wzh.codegen.biz.domain.dto.CodegenColumnDTO columnDTO : columnDTOs) {
            Map<String, Object> column = new HashMap<>();
            column.put("columnName", columnDTO.getColumnName());
            column.put("dataType", columnDTO.getColumnType());
            column.put("columnSize", columnDTO.getColumnLength());
            column.put("decimalDigits", columnDTO.getColumnScale());
            column.put("nullable", columnDTO.getIsNullable());
            column.put("columnComment", columnDTO.getColumnComment());
            column.put("columnDefault", columnDTO.getDefaultValue());
            column.put("isPrimaryKey", columnDTO.getIsPrimaryKey());
            column.put("isAutoIncrement", columnDTO.getIsAutoIncrement());
            // 新增：支持ON UPDATE CURRENT_TIMESTAMP等额外属性
            column.put("onUpdateCurrentTimestamp", columnDTO.getOnUpdateCurrentTimestamp());
            column.put("extra", columnDTO.getExtra());
            columns.add(column);
        }

        return columns;
    }

    /**
     * 转换字段信息用于代码生成
     */
    private List<Map<String, Object>> convertColumnsForGeneration(List<com.wzh.codegen.biz.domain.dto.CodegenColumnDTO> columns) {
        List<Map<String, Object>> columnMaps = new ArrayList<>();

        for (com.wzh.codegen.biz.domain.dto.CodegenColumnDTO column : columns) {
            Map<String, Object> columnMap = new HashMap<>();
            columnMap.put("columnName", column.getColumnName());
            columnMap.put("javaFieldName", column.getJavaFieldName());
            columnMap.put("javaFieldType", column.getJavaFieldType());
            columnMap.put("columnComment", column.getColumnComment());
            columnMap.put("isPrimaryKey", column.getIsPrimaryKey());
            columnMap.put("isAutoIncrement", column.getIsAutoIncrement());
            columnMap.put("isNullable", column.getIsNullable());
            columnMap.put("defaultValue", column.getDefaultValue());
            columnMaps.add(columnMap);
        }

        return columnMaps;
    }


    @Override
    public List<Map<String, Object>> getCommonFields() {
        List<Map<String, Object>> commonFields = new ArrayList<>();

        // 基于BaseEntity的通用字段
        commonFields.add(createFieldMap("create_by", "创建者", "String", "createBy", false, false, true, null));
        commonFields.add(createFieldMap("create_time", "创建时间", "LocalDateTime", "createTime", false, false, true, null));
        commonFields.add(createFieldMap("update_by", "更新者", "String", "updateBy", false, false, true, null));
        commonFields.add(createFieldMap("update_time", "更新时间", "LocalDateTime", "updateTime", false, false, true, null));
        commonFields.add(createFieldMap("del_flag", "删除标志", "Integer", "delFlag", false, false, true, "0"));

        return commonFields;
    }

    /**
     * 创建字段映射
     */
    private Map<String, Object> createFieldMap(String columnName, String comment, String javaType,
                                               String javaFieldName, boolean isPrimaryKey,
                                               boolean isAutoIncrement, boolean isNullable, String defaultValue) {
        Map<String, Object> field = new HashMap<>();
        field.put("columnName", columnName);
        field.put("columnComment", comment);
        field.put("javaFieldType", javaType);
        field.put("javaFieldName", javaFieldName);
        field.put("isPrimaryKey", isPrimaryKey);
        field.put("isAutoIncrement", isAutoIncrement);
        field.put("isNullable", isNullable);
        field.put("defaultValue", defaultValue);
        return field;
    }

    /**
     * 将生成的代码文件写入到磁盘指定位置
     *
     * @param files        生成的文件内容映射 (文件相对路径 -> 文件内容)
     * @param generatePath 生成路径
     * @param packageName  包名
     */
    private void writeFilesToDisk(Map<String, String> files, String generatePath, String packageName) {
        try {
            // 确保生成路径不为空
            if (generatePath == null || generatePath.trim().isEmpty()) {
                throw new CustomerException("生成路径不能为空");
            }

            // 创建基础目录
            Path basePath = Paths.get(generatePath);
            if (!Files.exists(basePath)) {
                Files.createDirectories(basePath);
                log.info("创建生成目录: {}", basePath.toAbsolutePath());
            }

            int successCount = 0;
            for (Map.Entry<String, String> entry : files.entrySet()) {
                String relativePath = entry.getKey();
                String content = entry.getValue();

                // 构建完整的文件路径
                Path filePath = basePath.resolve(relativePath);

                // 确保父目录存在
                Path parentDir = filePath.getParent();
                if (parentDir != null && !Files.exists(parentDir)) {
                    Files.createDirectories(parentDir);
                }

                // 写入文件
                Files.writeString(filePath, content,
                        StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);

                log.debug("成功写入文件: {}", filePath.toAbsolutePath());
                successCount++;
            }

            log.info("成功写入 {} 个文件到目录: {}", successCount, basePath.toAbsolutePath());
        } catch (IOException e) {
            log.error("写入文件到磁盘失败", e);
            throw new CustomerException("写入文件到磁盘失败: " + e.getMessage());
        }
    }

}